#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

void handler(int signo)
{
    printf("进程 %d 捕捉到了 %d 号信号\n", getpid(), signo);

    // 这里的 -1 表示父进程等待时，只要是已经退出了的子进程，都可以进行回收
    while (1)
    {
        pid_t ret = waitpid(-1, NULL, WNOHANG);
        if (ret > 0)
            printf("父进程: %d 已经成功回收了 %d 号进程\n", getpid(), ret);
        else
            break;
    }
    printf("子进程回收成功\n");
}

int main()
{
    signal(SIGCHLD, handler);

    // 创建10个子进程
    int n = 10;
    while (n--)
    {
        pid_t id = fork();

        if (id == 0)
        {
            int n = 5;
            while (n)
            {
                printf("子进程剩余生存时间: %d秒 [pid: %d  ppid: %d]\n", n--, getpid(), getppid());
                sleep(1);
            }

            // 子进程退出
            exit(-1);
        }
    }

    // 父进程很忙的话，可以去做自己的事
    while (1)
    {
        // TODO
        printf("父进程正在忙...\n");
        sleep(1);
    }

    return 0;
}

// volatile int flag = 0;   // 杜绝寄存器级别的优化

// void handler(int signo)
// {
//     printf("%d号信号已经成功发出了\n", signo);
//     flag = 1;
//     printf("flag的值已经更新了: %d\n", flag);
// }

// int main()
// {
//     signal(2, handler);
//     printf("flag的初始值为: %d\n", flag);

//     while(!flag);   // 故意不写 while 的代码块 { }

//     printf("进程已退出\n");

//     return 0;
// }